#define _CRT_SECURE_NO_WARNINGS 1
#include"contact_2.h"
//c语言课设
void InitStu_OS(Stu_OS* pc)
{
	assert(pc);
	pc->sz = 0;
	stu* ptr = (stu*)calloc(DEFAULT_SZ, sizeof(stu));
	if (NULL == ptr)
	{
		perror("InitStu_OS::calloc");
		return;
	}
	pc->data = ptr;
	pc->capacity = DEFAULT_SZ;
	
}
void Check_capacityStu_OS(Stu_OS* pc)
{
	if (pc->sz == pc->capacity)
	{
		stu* tmp = (stu*)realloc(pc->data, (pc->capacity*2) * sizeof(stu));
		if (tmp == NULL)
		{
			perror("Check_capacityStu_OS::realloc");
			return;
		}
		pc->data = tmp;
		pc->capacity*=2;
	}
}
void LoadStu_OS(Stu_OS * pc)
{
	
	FILE* pf = fopen("Stu_OS.txt", "rb");
	if (NULL == pf)
	{
		perror("LoadStu_OS::fopen");
	}
	else
	{
		stu tmp = { 0 };
		pc->sz = 0;
		int i = 0;
		while (fread(&tmp, sizeof(stu), 1, pf))
		{
			Check_capacityStu_OS(pc);
			pc->data[i] = tmp;
			pc->sz++;
			i++;
		}
		fclose(pf);
		pf = NULL;
	}
}

void AddStu_OS(Stu_OS* pc)
{
	assert(pc);
	printf("想要添加学生数据的个数:");
	int tmp = 0;
	scanf("%d", &tmp);
	while (tmp--)
	{
		Check_capacityStu_OS(pc);
		printf("------------------------\n");
		printf("学号：");
		scanf("%s", pc->data[pc->sz].num);
		printf("姓名：");
		scanf("%s", pc->data[pc->sz].name);
		printf("性别：");
		scanf("%s", pc->data[pc->sz].sex);
		printf("英语：");
		scanf("%d", &(pc->data[pc->sz].english));
		printf("数学：");
		scanf("%d", &(pc->data[pc->sz].math));
		printf("语文：");
		scanf("%d", &(pc->data[pc->sz].chinese));
		pc->data[pc->sz].sum = ((float)pc->data[pc->sz].english + (float)pc->data[pc->sz].math + (float)pc->data[pc->sz].chinese);
		pc->data[pc->sz].aver = (pc->data[pc->sz].sum) / 3;
		printf("平均成绩：%f\n", pc->data[pc->sz].aver);
		printf("综合成绩：%f\n", pc->data[pc->sz].sum);
		pc->sz++;
		printf("------------------------\n");
	}
}

void ShowStu_OS(Stu_OS* pc)
{
	assert(pc);
	printf("展示所有学生信息\n");
	if (pc->sz == 0)
	{
		printf("\a系统内尚无学生信息\n");
		return;
	}
	printf("%-20s\t%-10s\t%-4s\t%-6s\t%-6s\t%-6s\t%-6s\t%-6s\n", "学号", "姓名", "性别", "英语", "数学", "语文", "平均成绩", "综合成绩");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-10s\t%-4s\t%-6d\t%-6d\t%-6d\t%-6f\t%-6f\n",
				pc->data[i].num,
				pc->data[i].name,
				pc->data[i].sex,
				pc->data[i].english,
				pc->data[i].math,
				pc->data[i].chinese,
				pc->data[i].aver,
				pc->data[i].sum
		);
	}
}
void Search_menu()
{
	printf("------------------------\n");
	printf("请选择查找方式：\n");
	printf("1.姓名查找\n");
	printf("2.学号查找\n");
	printf("0.退出查找功能\n");
	printf("------------------------\n");
}
void SearchStu_OS(Stu_OS* pc)
{
	int input = 0;
	do
	{
		Search_menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			Search_nameStu_OS(pc);
			system("pause");
			system("cls");
			return;
		case 2:
			Search_numStu_OS(pc);
			system("pause");
			system("cls");
			return;
		case 0:
			printf("退出成功\n");
			system("pause");
			system("cls");
			return;
		default:
			printf("\a选择错误\n");
			printf("请重新选择\n");
		}
	} while (input);
}

int Findbyname(Stu_OS* pc, char name[])
{
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
			return i;
	}
	return -1;
}
void Search_nameStu_OS(Stu_OS* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("\a系统内尚无学生信息\n");
		return;
	}
	printf("请输入要查找学生的名字:");
	char tmp[NAME_MAX];
	scanf("%s", tmp);
	int pos = Findbyname(pc, tmp);
	if (-1 == pos)
	{
		printf("\a查无此人\n");
		return;
	}
	printf("%-20s\t%-10s\t%-4s\t%-6s\t%-6s\t%-6s\t%-6s\t%-6s\n", "学号", "姓名", "性别", "英语", "数学", "语文", "平均成绩", "综合成绩");
	printf("%-20s\t%-10s\t%-4s\t%-6d\t%-6d\t%-6d\t%-6f\t%-6f\n",
			pc->data[pos].num,
			pc->data[pos].name,
			pc->data[pos].sex,
			pc->data[pos].english,
			pc->data[pos].math,
			pc->data[pos].chinese,
			pc->data[pos].aver,
			pc->data[pos].sum
		);
}

void Search_numStu_OS(Stu_OS* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("\a系统内尚无学生信息\n");
		return;
	}
	printf("请输入要查找学生的学号:");
	char tmp[NUM_MAX];
	scanf("%s", tmp);
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].num, tmp) == 0)
		{
			printf("%-20s\t%-10s\t%-4s\t%-6s\t%-6s\t%-6s\t%-6s\t%-6s\n", "学号", "姓名", "性别", "英语", "数学", "语文", "平均成绩", "综合成绩");
			printf("%-20s\t%-10s\t%-4s\t%-6d\t%-6d\t%-6d\t%-6f\t%-6f\n",
				pc->data[i].num,
				pc->data[i].name,
				pc->data[i].sex,
				pc->data[i].english,
				pc->data[i].math,
				pc->data[i].chinese,
				pc->data[i].aver,
				pc->data[i].sum
			);
			return;
		}
	}
	printf("\a查无此人\n");
}

void ModifyStu_OS(Stu_OS* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("\a系统内尚无学生信息\n");
		return;
	}
	char name[NAME_MAX];
	char tmp[20] = {0};
	do
	{
		printf("请输入要查找学生的名字:");
		scanf("%s", name);
		int pos = Findbyname(pc, name);
		if (-1 == pos)
		{
			printf("\a查无此人\n");
			ShowStu_OS(pc);
			printf("是否继续查找？\n");
			printf("YES or NO\n");
			scanf("%s", tmp);
		}
		else
		{
			printf("确认修改？\n");
			int input = 0;
			do
			{
				printf("继续修改请输入“1”\n");
				printf("取消修改请输入“0”\n");
				scanf("%d", &input);
				if (input == 1)
				{
					printf("%-20s\t%-10s\t%-4s\t%-6s\t%-6s\t%-6s\t%-6s\t%-6s\n", "学号", "姓名", "性别", "英语", "数学", "语文", "平均成绩", "综合成绩");
					printf("%-20s\t%-10s\t%-4s\t%-6d\t%-6d\t%-6d\t%-6f\t%-6f\n",
						pc->data[pos].num,
						pc->data[pos].name,
						pc->data[pos].sex,
						pc->data[pos].english,
						pc->data[pos].math,
						pc->data[pos].chinese,
						pc->data[pos].aver,
						pc->data[pos].sum
					);
					printf("请重新输入信息:\n");
					printf("------------------------\n");
					printf("学号：");
					scanf("%s", pc->data[pos].num);
					printf("姓名：");
					scanf("%s", pc->data[pos].name);
					printf("性别：");
					scanf("%s", pc->data[pos].sex);
					printf("英语：");
					scanf("%d", &(pc->data[pos].english));
					printf("数学：");
					scanf("%d", &(pc->data[pos].math));
					printf("语文：");
					scanf("%d", &(pc->data[pos].chinese));
					pc->data[pos].sum = ((float)pc->data[pos].english + (float)pc->data[pos].math + (float)pc->data[pos].chinese);
					pc->data[pos].aver = (pc->data[pos].sum) / 3;
					printf("平均成绩：%f\n", pc->data[pos].aver);
					printf("综合成绩：%f\n", pc->data[pos].sum);
					printf("------------------------\n");
					printf("修改完成！\n");
					break;
				}
				else if (input == 0)
				{
					return;
				}
				else
				{
					printf("\a选择错误!\n");
					printf("请重新选择!\n");
				}
			} while (input);
		}
	} while (strcmp(tmp, "YES") == 0);
	printf("退出修改功能！\n");
}

void Sort_menu()
{
	printf("------------------------\n");
	printf("请选择排序方式:\n");
	printf("1.按学号排序\n");
	printf("2.按姓名排序\n");
	printf("3.按英语成绩排序\n");
	printf("4.按语文成绩排序\n");
	printf("5.按数学成绩排序\n");
	printf("6.按平均成绩排序\n");
	printf("7.按综合成绩排序\n");
	printf("0.退出排序功能\n");
	printf("------------------------\n");
}

int cmp_by_aver(const void* e1, const void* e2)
{
	if ((((stu*)e2)->aver - ((stu*)e1)->aver) < 0)
		return -1;
	else
		return 1;
}

int cmp_by_sum(const void* e1, const void* e2)
{
	if ((((stu*)e2)->sum - ((stu*)e1)->sum) < 0)
		return -1;
	else
		return 1;
}
int cmp_by_chinese(const void* e1, const void* e2)
{
	return ((stu*)e2)->chinese - ((stu*)e1)->chinese;
}

int cmp_by_english(const void* e1, const void* e2)
{
	return ((stu*)e2)->english - ((stu*)e1)->english;
}

int cmp_by_math(const void* e1, const void* e2)
{
	return ((stu*)e2)->math - ((stu*)e1)->math;
}

int cmp_by_name(const void* e1, const void* e2)
{
	return strcmp(((stu*)e1)->name, ((stu*)e2)->name);
}

int cmp_by_num(const void* e1, const void* e2)
{
	return strcmp(((stu*)e1)->num, ((stu*)e2)->num);
}

void SortStu_OS(Stu_OS* pc)
{

	assert(pc);
	if (pc->sz == 0)
	{
		printf("\a系统内尚无学生信息\n");
		return;
	}
	int input = 0;
	do
	{
		Sort_menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("按学号排序\n");
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_by_num);
			input = 0;
			break;
		case 2:
			printf("按姓名排序\n");
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_by_name);
			input = 0;
			break;
		case 3:
			printf("按英语成绩排序\n");
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_by_english);
			input = 0;
			break;
		case 4:
			printf("按语文成绩排序\n");
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_by_chinese);
			input = 0;
			break;
		case 5:
			printf("按数学成绩排序\n");
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_by_math);
			input = 0;
			break;
		case 6:
			printf("按平均成绩排序\n");
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_by_aver);
			input = 0;
			break;
		case 7:
			printf("按综合成绩排序\n");
			qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_by_sum);
			input = 0;
			break;
		case 0:
			printf("退出成功！\n");
			return;
		default:
			printf("选择错误！\n");
			printf("请重新选择：\n");
		}
	} while (input);
	printf("排序完成\n");
	ShowStu_OS(pc);
}

void DelStu_OS(Stu_OS* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("\a系统内尚无学生信息\n");
		return;
	}
	ShowStu_OS(pc);
	printf("请输入要删除的学生名字:");
	char tmp[NAME_MAX];
	scanf("%s", tmp);
	int pos = Findbyname(pc, tmp);
	if (-1 == pos)
	{
		printf("\a查无此人\n");
		return;
	}
	if (pos == pc->sz - 1)
		pc->sz--;
	else
	{
		for (int i = pos; i < pc->sz - 1; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}
		pc->sz--;
	}
	printf("删除完成\n");
}

void SaveStu_OS(Stu_OS* pc)
{
	FILE* pf = fopen("Stu_OS.txt", "wb");
	if (NULL == pf)
	{
		perror("SaveStu_OS::fopen");
	}
	else
	{
		for (int i = 0; i < pc->sz; i++)
		{
			fwrite(pc->data + i, sizeof(stu), 1, pf);
		}
		fclose(pf);
		pf = NULL;
		printf("保存成功\n");
	}
}
void Mine()
{
	printf("--------个人信息--------\n");
	printf("        云中清风\n");
	printf("年龄：18\n");
	printf("大学：华东交通大学\n");
	printf("专业：通信工程\n");
	printf("爱好：敲代码\n");
	printf("住址：中国\n");
	printf("小组：周文锦\n");
}

void DestroyStu_OS(Stu_OS* pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	pc = NULL;
}